"""
test.py - 装饰器

装饰器：用一个函数去装饰另一个函数或类，为其提供额外的能力，实现了一种名为代理模式的经典设计模式。
横切关注功能（cross-concern）：跟正常的业务没有必然联系的功能，这样的功能最适合用装饰器（代理模式）来实现。

作业：写一个装饰器，如果函数返回了字符串，就将字符串每个单词首字母大写。
预习：带参数的装饰器（装饰器本身也可以参数化）---> 尝试将刚才的装饰器记录时间的功能放到数据库或文件
"""
import random
import time
from functools import wraps


# 装饰器函数的参数是被装饰的函数，它返回的是带有装饰功能的函数
def log_time(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        ret_value = func(*args, **kwargs)
        end = time.time()
        print(f'{func.__name__}执行时间: {end - start:.3f}秒')
        return ret_value

    return wrapper


@log_time
def download(filename):
    print(f'开始下载 {filename}.')
    time.sleep(random.randrange(3, 7))
    print(f'{filename} 下载完成.')


@log_time
def upload(filename):
    print(f'开始上传 {filename}.')
    time.sleep(random.randrange(5, 9))
    print(f'{filename} 上传完成.')


if __name__ == '__main__':
    # download = log_time(download)
    download('Python从入门到住院.pdf')
    upload('MySQL从删库到跑路.avi')

    # 取消装饰器（得到被装饰之前的原函数）
    download.__wrapped__('Linux从精通到放弃.pdf')
